package org.object;

import com.google.common.collect.ComparisonChain;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
        
        // 1.equals
        // 当一个对象中的字段可以为null时，实现Object.equals方法会很痛苦，因为不得不分别对它们进行null检查。使用Objects.equal帮助你执行null敏感的equals判断，从而避免抛出NullPointerException
        // 注意：JDK7引入的Objects类提供了一样的方法Objects.equals。
        System.out.println(java.util.Objects.equals("a", "a")); // true
        System.out.println(java.util.Objects.equals(null, "a")); // false
        System.out.println(java.util.Objects.equals("a", null)); // false
        System.out.println(java.util.Objects.equals(null, null)); // true
        
        // 2.hashCode
        // 用对象的所有字段作散列[hash]运算应当更简单。Guava的Objects.hashCode(Object...)会对传入的字段序列计算出合理的、
        // 顺序敏感的散列值。你可以使用Objects.hashCode(field1, field2, …, fieldn)来代替手动计算散列值。
        // 注意：JDK7引入的Objects类提供了一样的方法Objects.hash(Object...)
        System.out.println(java.util.Objects.hash("a", "b", "c"));
        System.out.println("abc".hashCode());
        
        // 3. toString 
        // 好的toString方法在调试时是无价之宝，但是编写toString方法有时候却很痛苦。使用 Objects.toStringHelper可以轻松编写有用的toString方法
        // toStringHelper方法未找到
        
        // 4. compare/compareTo
        //Guava提供了ComparisonChain。
        //ComparisonChain执行一种懒比较：它执行比较操作直至发现非零的结果，在那之后的比较输入将被忽略。
        Foo firstOne = new Foo("123", 1, "321");     
        Foo secondOne = new Foo("123", 1, "321");
        Foo thirdOne = new Foo("123", 2, "321");
        System.out.println(firstOne.compareTo(secondOne));
        System.out.println(firstOne.compareTo(thirdOne));
    }
    
    public static class Foo {
    	private String aString;
    	private Integer anInt;
    	private String str;
    	
    	public Foo(String aString, Integer anInt, String str) {
    		this.aString = aString;
    		this.anInt = anInt;
    		this.str = str;
    	}
    	
    	public int compareTo(Foo that) {
    		return ComparisonChain.start()
    				.compare(this.aString, that.aString)
    				.compare(this.anInt, that.anInt)
    				.compare(this.str, that.str)
    				.result();
    	}
    }
}
